extends Node2D
const BOX = preload("uid://duu8cxfil60ox")
const EYE = preload("uid://dr73qgy5q7w1v")

const eye_default_scale=Vector2(0.15,0.15)

enum PupilFollowTarget{
	MOUSE,
	PLAYER,
	NONE
}
@export var pupil_follow_target:PupilFollowTarget = PupilFollowTarget.MOUSE
@export var eye_freeze_rotation:bool=true
@export var eye_scale_follow_box:bool=false
var eye: Sprite2D
var box: Sprite2D
var eye_material:ShaderMaterial
var _len_x:float
var _len_y:float
var _open_progress:float:
	set(v):
		_open_progress=clamp(v,0.0,2.0)
		eye_material.set_shader_parameter("y_scale",_open_progress)
var _target_open_progress:float = 1.0
var _pupil_radius:float:
	set(v):
		_pupil_radius=clamp(v,0.0,0.3)
		eye_material.set_shader_parameter("tk_r",_pupil_radius)
var _target_pupil_radius:float = 0.2
var _eye_color:Vector3:
	set(v):
		_eye_color = v.clamp(Vector3.ZERO,Vector3.ONE)
		eye_material.set_shader_parameter("eye_w_color",_eye_color)
var _target_eye_color:Vector3 = Vector3(0.787,0.787,0.787)
var _pupil_color:Vector3:
	set(v):
		_pupil_color = v.clamp(Vector3.ZERO,Vector3.ONE)
		eye_material.set_shader_parameter("eye_color",_pupil_color)
var _target_pupil_color:Vector3 = Vector3(0.084,0.084,0.084)
var _look_at_position:Vector2:
	set(v):
		_look_at_position=v.clamp(-Vector2.ONE/2,Vector2.ONE/2)
		if ensure_pupil_be_see:
			_look_at_position=_look_at_position.normalized()*0.3
		if not eye_freeze_rotation:
			eye_material.set_shader_parameter("eye_offset_x",_look_at_position.rotated(-self.rotation).x)
			eye_material.set_shader_parameter("eye_offset_y",_look_at_position.rotated(-self.rotation).y)
		else:
			eye_material.set_shader_parameter("eye_offset_x",_look_at_position.x)
			eye_material.set_shader_parameter("eye_offset_y",_look_at_position.y)
func _ready() -> void:
	box=find_child("Box")
	eye=find_child("Eye")
	if box==null:
		box=BOX.instantiate()
		add_child(box)
		if Engine.is_editor_hint():box.owner=get_tree().edited_scene_root
		else:box.owner=self
	if eye==null:
		eye=EYE.instantiate()
		add_child(eye)
		if Engine.is_editor_hint():eye.owner=get_tree().edited_scene_root
		else:eye.owner=self
	eye_material=eye.material
	eye_material=eye_material.duplicate()
	eye.material=eye_material
	box.material=box_material

func reset()->void:
	eye_material.set_shader_parameter("tk_r",0.2)
	eye_material.set_shader_parameter("eye_offset_x",0.0)
	eye_material.set_shader_parameter("eye_offset_y",0.0)
	eye_material.set_shader_parameter("x_scale",2.0)
	eye_material.set_shader_parameter("y_scale",1.0)
	eye_material.set_shader_parameter("eye_color",Vector3(0.084,0.084,0.084))
	eye_material.set_shader_parameter("eye_w_color",Vector3(0.787,0.787,0.787))
	box.self_modulate = Color(0.692, 0.692, 0.692, 1.0)
var _my_screen_pos:Vector2
@warning_ignore("unused_parameter")
func _physics_process(delta: float) -> void:
	_my_screen_pos=get_global_transform_with_canvas().get_origin()
func _process(delta: float) -> void:
	if eye_freeze_rotation:eye.global_rotation=0
	eye.scale=box.scale*eye_default_scale if eye_scale_follow_box else eye_default_scale
	if not Engine.is_editor_hint() and pupil_follow_target==PupilFollowTarget.MOUSE:
		if get_viewport_rect().has_point(Global.mouse_position):
			if Global.has_player:
				_len_x = _my_screen_pos.x-Global.mouse_position.x
				_len_y = _my_screen_pos.y-Global.mouse_position.y
				_look_at_position=_look_at_position.move_toward(Vector2(clamp(-_len_x/1152,-0.5,0.5),clamp(-_len_y/648,-0.5,0.5)),delta*5)
			else:
				_len_x = self.get_global_transform_with_canvas().get_origin().x-Global.mouse_position.x
				_len_y = self.get_global_transform_with_canvas().get_origin().y-Global.mouse_position.y
				_look_at_position=_look_at_position.move_toward(Vector2(clamp(-_len_x/1152,-0.5,0.5),clamp(-_len_y/648,-0.5,0.5)),delta*5)
		else:_look_at_position=_look_at_position.move_toward(Vector2.ZERO,delta*5)
	elif not Engine.is_editor_hint() and pupil_follow_target==PupilFollowTarget.PLAYER:
		if Global.has_player:
				_len_x = self.global_position.x-Global.player_position.x
				_len_y = self.global_position.y-Global.player_position.y
				_look_at_position=_look_at_position.move_toward(Vector2(clamp(-_len_x/1152,-0.5,0.5),clamp(-_len_y/648,-0.5,0.5)),delta*5)
		
	if _target_open_progress!=_open_progress:
		_open_progress = move_toward(_open_progress,_target_open_progress,delta*10)
	if _target_pupil_radius!=_pupil_radius:
		_pupil_radius = move_toward(_pupil_radius,_target_pupil_radius,delta*10)
	if _target_eye_color!=_eye_color:
		_eye_color = _eye_color.move_toward(_target_eye_color,delta*10)
	if _target_pupil_color!=_pupil_color:
		_pupil_color = _pupil_color.move_toward(_target_pupil_color,delta*10)
##0-2
@export_range(0,2,0.1) var open_progress:float=1.0:set=set_open_progress,get=get_open_progress
func set_open_progress(progress:float)->void:_target_open_progress=clamp(progress,0.0,2.0)
func get_open_progress()->float:return _target_open_progress
##0-0.3
@export_range(0,0.3,0.01) var pupil_radius:float=0.2:set=set_pupil_radius,get=get_pupil_radius
func set_pupil_radius(radius:float)->void:_target_pupil_radius=clamp(radius,0.0,0.3)
func get_pupil_radius()->float:return _target_pupil_radius
@export var pupil_color:Color=Color(0.084,0.084,0.084):set=set_pupil_color,get=get_pupil_color
func set_pupil_color(color:Color)->void:_target_pupil_color=Vector3(color.r,color.g,color.b)
func get_pupil_color()->Color:return Color(_target_pupil_color.x,_target_pupil_color.y,_target_pupil_color.z,1.0)
@export var eye_color:Color=Color(0.787,0.787,0.787):set=set_eye_color,get=get_eye_color
func set_eye_color(color:Color)->void:_target_eye_color=Vector3(color.r,color.g,color.b)
func get_eye_color()->Color:return Color(_target_eye_color.x,_target_eye_color.y,_target_eye_color.z,1.0)
@export_range(0.0,1.0,0.1) var eye_alpha:float:set=set_eye_alpha,get=get_eye_alpha
func set_eye_alpha(alpha:float)->void:
	if not is_node_ready():await ready#!!
	eye_material.set_shader_parameter("alpha",clamp(alpha,0.0,1.0))
func get_eye_alpha()->float:return eye_material.get_shader_parameter("alpha")
@export var box_color:Color=Color(0.692, 0.692, 0.692, 1.0):set=set_box_color,get=get_box_color
func set_box_color(color:Color)->void:
	if not is_node_ready():await ready#!!
	box.self_modulate = color
func get_box_color()->Color:return box.self_modulate
@export var box_scale:Vector2=Vector2(1.0,1.0):set=set_box_scale,get=get_box_scale
func set_box_scale(sca:Vector2)->void:
	if not is_node_ready():await ready#!!
	box.scale=sca
func get_box_scale()->Vector2:return box.scale
@export var box_skin:Texture2D:set=set_box_skin,get=get_box_skin
func set_box_skin(tex:Texture2D)->void:
	if not is_node_ready():await ready#!!
	box.texture=tex
func get_box_skin()->Texture2D:return box.texture
@export var box_material:ShaderMaterial:set=set_box_material,get=get_box_material
func set_box_material(mat:ShaderMaterial)->void:
	if not is_node_ready():await ready#!!
	box.material=mat
func get_box_material()->ShaderMaterial:return box.material
@export var ensure_pupil_be_see:bool=false
##(-0.5,-0.5)-(0.5,0.5)
@export var look_at_position:Vector2:set=set_look_at_position,get=get_look_at_position
func set_look_at_position(pos:Vector2)->void:
	if pupil_follow_target!=PupilFollowTarget.NONE:return
	look_at_position=pos.clamp(-Vector2.ONE/2,Vector2.ONE/2)
	_look_at_position=look_at_position
func get_look_at_position()->Vector2:
	return look_at_position
